//
//  WkSpringLayerAnimation.m
//  KKANIMATION
//
//  Created by TOPTEAM on 16/10/17.
//  Copyright © 2016年 TOPTEAM. All rights reserved.
//

#import "WkSpringLayerAnimation.h"

@implementation WkSpringLayerAnimation

+ (instancetype)sharedAnimManager {
    
    static WkSpringLayerAnimation * animManager = nil;
    static dispatch_once_t predicate;
    dispatch_once(&predicate ,^{
        animManager = [[WkSpringLayerAnimation alloc]init];
    });
    return animManager;
}

#pragma mark==================Normal Anim -- 线性函数========================
- (CAKeyframeAnimation *)createBasicAnima:(NSString *)keypath
                                 duration:(CFTimeInterval)duration
                                fromValue:(id)fromValue
                                  toValue:(id)toValue{

    CAKeyframeAnimation * anim =
    [CAKeyframeAnimation animationWithKeyPath:keypath];
    anim.values =
    [self basicAnimationValues:fromValue toValue:toValue duration:duration];
    anim.duration = duration;
  
    anim.fillMode = kCAFillModeForwards;
  
    anim.removedOnCompletion = NO;
    
    return anim;
}
- (NSMutableArray *)basicAnimationValues:(id)fromValue
                                 toValue:(id)toValue
                                duration:(CGFloat)duration {
    NSInteger numOfFrames = duration * 60;
    NSMutableArray *values = [NSMutableArray arrayWithCapacity:numOfFrames];
    for (NSInteger i = 0; i < numOfFrames; i++) {
        [values addObject:@(0.0)];
    }
    CGFloat diff = [toValue floatValue] - [fromValue floatValue];
    for (NSInteger frame = 0; frame < numOfFrames; frame++) {
        
        CGFloat x = (CGFloat)frame / (CGFloat)numOfFrames;
        CGFloat value = [fromValue floatValue] + diff * x;
        values[frame] = @(value);
    }
    return values;
}
#pragma mark==================Spring Anim -- 弹性曲线========================
- (CAKeyframeAnimation *)createSpringAnima:(NSString *)keypath
                                  duration:(CFTimeInterval)duration
                    usingSpringWithDamping:(CGFloat)damping
                     initialSpringVelocity:(CGFloat)velocity
                                 fromValue:(id)fromValue
                                   toValue:(id)toValue{
    
    CGFloat dampingFactor = 10.0;
    CGFloat velocityFactor = 10.0;
    NSMutableArray *values = [self springAnimationValues:fromValue
                                                 toValue:toValue
                                  usingSpringWithDamping:damping * dampingFactor
                                   initialSpringVelocity:velocity * velocityFactor
                                                duration:duration];
    CAKeyframeAnimation *anim =
    [CAKeyframeAnimation animationWithKeyPath:keypath];
    anim.values = values;
    anim.duration = duration;
    anim.fillMode = kCAFillModeForwards;
    anim.removedOnCompletion = NO;
    
    return anim;
    
}
- (NSMutableArray *)springAnimationValues:(id)fromValue
                                  toValue:(id)toValue
                   usingSpringWithDamping:(CGFloat)damping
                    initialSpringVelocity:(CGFloat)velocity
                                 duration:(CGFloat)duration {
    // 60个关键帧
    NSInteger numOfFrames = duration * 60;
    NSMutableArray *values = [NSMutableArray arrayWithCapacity:numOfFrames];
    for (NSInteger i = 0; i < numOfFrames; i++) {
        [values addObject:@(0.0)];
    }
    
    //差值
    CGFloat diff = [toValue floatValue] - [fromValue floatValue];
    for (NSInteger frame = 0; frame < numOfFrames; frame++) {
        CGFloat x = (CGFloat)frame / (CGFloat)numOfFrames;
        CGFloat value = [toValue floatValue] -
        diff * (pow(M_E, -damping * x) *
                cos(velocity * x)); // y = 1-e^{-5x} * cos(30x)
        values[frame] = @(value);
    }
    return values;
}

#pragma mark==================Curve Anim -- 二次平滑抛物函数========================
- (CAKeyframeAnimation *)createCurveAnima:(NSString *)keypath
                                 duration:(CFTimeInterval)duration
                                fromValue:(id)fromValue
                                  toValue:(id)toValue{
    CAKeyframeAnimation *anim =
    [CAKeyframeAnimation animationWithKeyPath:keypath];
    anim.values =
    [self curveAnimationValues:fromValue toValue:toValue duration:duration];
    anim.duration = duration;
    anim.fillMode = kCAFillModeForwards;
    anim.removedOnCompletion = NO;
    
    return anim;
    
}
- (NSMutableArray *)curveAnimationValues:(id)fromValue
                                 toValue:(id)toValue
                                duration:(CGFloat)duration {
    NSInteger numOfFrames = duration * 60;
    NSMutableArray *values = [NSMutableArray arrayWithCapacity:numOfFrames];
    for (NSInteger i = 0; i < numOfFrames; i++) {
        [values addObject:@(0.0)];
    }
    
    CGFloat diff = [toValue floatValue] - [fromValue floatValue];
    for (NSInteger frame = 0; frame < numOfFrames; frame++) {
        
        CGFloat x = (CGFloat)frame / (CGFloat)numOfFrames;
        CGFloat value = [fromValue floatValue] + diff * (-4 * x * (x - 1));
        values[frame] = @(value);
    }
    return values;
}


#pragma mark==================Curve Anim -- 抛到一半的二次平滑抛物函数========================
- (CAKeyframeAnimation *)createHalfCurveAnima:(NSString *)keypath
                                     duration:(CFTimeInterval)duration
                                    fromValue:(id)fromValue
                                      toValue:(id)toValue {
    CAKeyframeAnimation *anim =
    [CAKeyframeAnimation animationWithKeyPath:keypath];
    anim.values = [self halfCurveAnimationValues:fromValue
                                         toValue:toValue
                                        duration:duration];
    anim.duration = duration;
    anim.fillMode = kCAFillModeForwards;
    anim.removedOnCompletion = NO;
    
    return anim;
}
- (NSMutableArray *)halfCurveAnimationValues:(id)fromValue
                                     toValue:(id)toValue
                                    duration:(CGFloat)duration {
    NSInteger numOfFrames = duration * 60;
    NSMutableArray *values = [NSMutableArray arrayWithCapacity:numOfFrames];
    for (NSInteger i = 0; i < numOfFrames; i++) {
        [values addObject:@(0.0)];
    }
    CGFloat diff = [toValue floatValue] - [fromValue floatValue];
    for (NSInteger frame = 0; frame < numOfFrames; frame++) {
        
        CGFloat x = (CGFloat)frame / (CGFloat)numOfFrames;
        CGFloat value = [fromValue floatValue] + diff * (-x * (x - 2));
        values[frame] = @(value);
    }
    return values;
}
- (CAKeyframeAnimation *)Line_Move_Anima:(NSString *)keypath
                                 duration:(CFTimeInterval)duration
                              CenterPoint:(CGPoint)CenterPoint withTag:(int )tag{
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
    animation.keyPath = keypath;
    animation.repeatCount=MAXFLOAT;
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;
    animation.duration = duration;
    animation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    //    animation.delegate=self;
    //A
    CGFloat Marin;
    CGFloat Marin_2=0.5;
    CGFloat Sin45=0.850903524;
    
    
    
    CGFloat point_x=CenterPoint.x;
    
    CGFloat point_y=CenterPoint.y;

    CGPoint A_point =CenterPoint;
    
    CGPoint B_point;
    CGPoint C_point;
    
    //A->B
    float t1=1.0;
    float t2=0.5;
    if (tag==1) {
        
        Marin = 4;
        
        B_point =CGPointMake(point_x+Marin*Sin45, point_y+Marin*Sin45);

        C_point =CGPointMake(point_x+Marin*Sin45-Marin_2, point_y+Marin*Sin45-Marin_2);
    }else if(tag==2){
        
        Marin = 3;
        
        B_point =CGPointMake(point_x+Marin*Sin45, point_y-Marin*Sin45);

        C_point =CGPointMake(point_x+Marin*Sin45-Marin_2, point_y-Marin*Sin45-Marin_2);
    }else if(tag==3){
        
        Marin = 4;
        
        B_point =CGPointMake(point_x-Marin*Sin45, point_y+Marin*Sin45);

        C_point =CGPointMake(point_x-Marin*Sin45-Marin_2, point_y+Marin*Sin45-Marin_2);
    }else if(tag==4){
        
        Marin = 3;
        
        B_point =CGPointMake(point_x-Marin*Sin45, point_y-Marin*Sin45);

        C_point =CGPointMake(point_x-Marin*Sin45-Marin_2, point_y-Marin*Sin45-Marin_2);
    }
    
    
    NSMutableArray * marr_all_valus=[[NSMutableArray alloc]init];
    [marr_all_valus addObjectsFromArray: [self BasicAnimationValues:A_point toValue:B_point duration:t1]];
    [marr_all_valus addObjectsFromArray: [self BasicAnimationValues:B_point toValue:C_point duration:t2]];
    [marr_all_valus addObjectsFromArray: [self BasicAnimationValues:C_point toValue:A_point duration:t1]];
    
    animation.values = marr_all_valus;
    return animation;

}


-(NSMutableArray *)BasicAnimationValues:(CGPoint)fromValue toValue:(CGPoint)toValue duration:(CGFloat)duration {
    
    NSInteger numOfFrames = duration * 60;
    NSMutableArray *values = [NSMutableArray arrayWithCapacity:numOfFrames];
    for (NSInteger i = 0; i < numOfFrames; i++) {
        [values addObject:[NSValue valueWithCGPoint:CGPointMake(200, 200)]];
    }

    
    CGFloat diffX = toValue.x - fromValue.x ;
    CGFloat diffY = toValue.y - fromValue.y ;
    for (NSInteger frame = 0; frame < numOfFrames; frame++) {
        CGFloat diff_count = (CGFloat)frame / (CGFloat)numOfFrames;
        CGFloat value_X = fromValue.x + diffX * diff_count;
        CGFloat value_Y = fromValue.y + diffY * diff_count;
        NSValue *value_point=[NSValue valueWithCGPoint:CGPointMake(value_X, value_Y)];
        values[frame] = value_point;
    }
    return values;
    
    
}



@end


















